package cn.iocoder.yudao.module.reading.convert.punch;

import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.reading.controller.app.punch.vo.*;
import cn.iocoder.yudao.module.reading.dal.dataobject.punch.PunchRecordDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 打卡 Convert
 *
 * @author 李晨
 */
@Mapper
public interface PunchConvert {

    PunchConvert INSTANCE = Mappers.getMapper(PunchConvert.class);

    /**
     * 转换为用户统计响应 VO
     *
     * @param totalPunchDays      总打卡天数
     * @param consecutiveDays     连续打卡天数
     * @param maxConsecutiveDays  最长连续打卡天数
     * @param thisMonthPunchDays  本月打卡天数
     * @param totalReadingTime    总阅读时长
     * @param totalBooksRead      总阅读绘本数
     * @param averageReadingTime  平均阅读时长
     * @param punchRate          打卡率
     * @param monthlyStats       月度统计
     * @param weeklyStats        周统计
     * @return 用户统计响应 VO
     */
    default UserStatsRespVO convertToUserStatsRespVO(Integer totalPunchDays, Integer consecutiveDays,
                                                    Integer maxConsecutiveDays, Integer thisMonthPunchDays,
                                                    Integer totalReadingTime, Integer totalBooksRead,
                                                    Integer averageReadingTime, Double punchRate,
                                                    List<UserStatsRespVO.MonthlyStatsVO> monthlyStats,
                                                    List<UserStatsRespVO.WeeklyStatsVO> weeklyStats) {
        UserStatsRespVO vo = new UserStatsRespVO();
        
        vo.setTotalPunchDays(totalPunchDays != null ? totalPunchDays : 0);
        vo.setConsecutiveDays(consecutiveDays != null ? consecutiveDays : 0);
        vo.setMaxConsecutiveDays(maxConsecutiveDays != null ? maxConsecutiveDays : 0);
        vo.setThisMonthPunchDays(thisMonthPunchDays != null ? thisMonthPunchDays : 0);
        vo.setTotalReadingTime(totalReadingTime != null ? totalReadingTime / 60 : 0); // 转换为分钟
        vo.setTotalBooksRead(totalBooksRead != null ? totalBooksRead : 0);
        vo.setAverageReadingTime(averageReadingTime != null ? averageReadingTime / 60 : 0); // 转换为分钟
        vo.setPunchRate(punchRate != null ? punchRate : 0.0);
        vo.setMonthlyStats(monthlyStats);
        vo.setWeeklyStats(weeklyStats);
        
        return vo;
    }

    /**
     * 转换为完整打卡日历响应 VO
     *
     * @param totalPunchDays     总打卡天数
     * @param consecutiveDays    连续打卡天数
     * @param thisMonthPunchDays 本月打卡天数
     * @param calendarData       日历数据
     * @param recentPunches      最近打卡记录
     * @return 完整打卡日历响应 VO
     */
    default PunchCalendarAllRespVO convertToPunchCalendarAllRespVO(Integer totalPunchDays, Integer consecutiveDays,
                                                                  Integer thisMonthPunchDays,
                                                                  Map<String, PunchCalendarAllRespVO.PunchDayInfo> calendarData,
                                                                  List<PunchRecordRespVO> recentPunches) {
        PunchCalendarAllRespVO vo = new PunchCalendarAllRespVO();
        
        vo.setTotalPunchDays(totalPunchDays != null ? totalPunchDays : 0);
        vo.setConsecutiveDays(consecutiveDays != null ? consecutiveDays : 0);
        vo.setThisMonthPunchDays(thisMonthPunchDays != null ? thisMonthPunchDays : 0);
        vo.setCalendarData(calendarData);
        vo.setRecentPunches(recentPunches);
        
        return vo;
    }

    /**
     * 转换打卡记录为日历数据
     *
     * @param punchRecords 打卡记录列表
     * @return 日历数据Map
     */
    default Map<String, PunchCalendarAllRespVO.PunchDayInfo> convertToCalendarData(List<PunchRecordDO> punchRecords) {
        return punchRecords.stream()
                .collect(Collectors.toMap(
                        record -> record.getPunchDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")),
                        record -> {
                            PunchCalendarAllRespVO.PunchDayInfo dayInfo = new PunchCalendarAllRespVO.PunchDayInfo();
                            dayInfo.setHasPunch(true);
                            dayInfo.setBookCount(record.getBookCount());
                            // TODO: 设置阅读时长和心情
                            dayInfo.setReadingTime(0);
                            dayInfo.setMood("开心");
                            return dayInfo;
                        }
                ));
    }

    /**
     * 转换为月度统计VO
     *
     * @param monthlyData 月度数据Map
     * @return 月度统计VO列表
     */
    default List<UserStatsRespVO.MonthlyStatsVO> convertToMonthlyStats(Map<String, Map<String, Integer>> monthlyData) {
        return monthlyData.entrySet().stream()
                .map(entry -> {
                    UserStatsRespVO.MonthlyStatsVO monthlyVO = new UserStatsRespVO.MonthlyStatsVO();
                    monthlyVO.setMonth(entry.getKey());
                    
                    Map<String, Integer> data = entry.getValue();
                    monthlyVO.setPunchDays(data.getOrDefault("punchDays", 0));
                    monthlyVO.setReadingTime(data.getOrDefault("readingTime", 0) / 60); // 转换为分钟
                    monthlyVO.setBookCount(data.getOrDefault("bookCount", 0));
                    
                    return monthlyVO;
                })
                .collect(Collectors.toList());
    }

    /**
     * 转换为周统计VO
     *
     * @param weeklyData 周数据Map
     * @return 周统计VO列表
     */
    default List<UserStatsRespVO.WeeklyStatsVO> convertToWeeklyStats(Map<String, Map<String, Integer>> weeklyData) {
        return weeklyData.entrySet().stream()
                .map(entry -> {
                    UserStatsRespVO.WeeklyStatsVO weeklyVO = new UserStatsRespVO.WeeklyStatsVO();
                    weeklyVO.setWeek(entry.getKey());
                    
                    Map<String, Integer> data = entry.getValue();
                    weeklyVO.setPunchDays(data.getOrDefault("punchDays", 0));
                    weeklyVO.setReadingTime(data.getOrDefault("readingTime", 0) / 60); // 转换为分钟
                    weeklyVO.setBookCount(data.getOrDefault("bookCount", 0));
                    
                    return weeklyVO;
                })
                .collect(Collectors.toList());
    }

}
